package com.mark.common.utils;

import com.google.common.collect.Maps;
import com.mark.common.enums.PropertiesEnum;
import com.mark.common.exception.ImageException;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;

/**
 * @Description: 图片处理工具类
 * @Author: Mark
 * @CreateDate: 2018/4/12.
 * @Version: 2.0
 * @Copyright : 豆浆油条个人非正式工作室
 */
@Slf4j
public class ImageUtil {

    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    private static final Random r = new Random();
    private static String separator = System.getProperty(PropertiesEnum.FILE_SEPARATOR.getPropertiesName());

    //获取新生的文件名
    public static String getNewFileName(String fileName) {
        String fileExtensionName = fileName.substring(fileName.lastIndexOf(".") + 1);//获取扩展名
        int randomNum = r.nextInt(89999) + 10000;// r.nextInt(89999)：0<x<89999
        String nowTimeStr = sDateFormat.format(new Date());
        return nowTimeStr + "-" + randomNum + "." + fileExtensionName;
    }

    //获取上传图片的绝对路径
    public static String getAbsolutePath(String targetAddress) {
        String absolutePath = PathUtil.getImageBasePath() + targetAddress;
        return absolutePath;
    }

    //加上水印
    public static File generateThumbnail(File file, String targetAddress) {
        String fileNewName = file.getName();
        String absolutePath = getAbsolutePath(targetAddress);
        makeDirPath(absolutePath);
        try {
            Thumbnails.
                    of(file)
                    .size(337, 640)
                    //.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/image/watermark.jpg")),1.0f)
                    .outputQuality(0.8f)
                    .toFile(absolutePath + fileNewName);
        } catch (IOException e) {
            log.error("生成水印图片异常：{}", e.getMessage());
        }
        log.info("文件通过本地方法保存");
        return new File(absolutePath + fileNewName);
    }

    /**
     * 对文件进行压缩处理
     * <p>
     * 版本二：Springboot调用的方法
     *
     * @param multipartFile ：原始的文件（即从前端接受的文件流）
     * @param role          ：角色（用户图片，商品图片等）
     * @return 根据不同的角色对图片进行不同的比例压缩处理
     */
    public static Map<String, Object> generateThumbnail(MultipartFile multipartFile, String role) {
        String localBasePath = PathUtil.getImageBasePath();
        makeDirPath(localBasePath);

        if (StringUtils.isBlank(multipartFile.getOriginalFilename())) {
            throw new ImageException("代理处理源文件的原始文件名不能为空");
        }

        String localFilePath = localBasePath + separator + multipartFile.getOriginalFilename();
        File file = new File(localFilePath);
        try {
            //1.multipartFile装换为本地的file
            multipartFile.transferTo(file);
        } catch (IOException e) {
            log.error("MultipartFile装换为File异常" + e.getMessage());
            throw new ImageException(e.getMessage());
        }

        //2.Thumbnails处理压缩处理
        //输出图片的宽度
        int width = 500;
        //输出图片的高度
        int height = 500;
        if (StringUtils.equals(role, "user")) {
            width = 300;
            height = 300;
        }
        //压缩文件的输出路径
        String outPutFilePath = file.getAbsolutePath();
        try {
            Thumbnails
                    .of(file)
                    .forceSize(width, height)
                    .toFile(outPutFilePath);
        } catch (IOException e) {
            log.error("Thumbnails处理图片异常:" + e.getMessage());
            throw new ImageException(e.getMessage());
        }

        //重新获取MultipartFile格式的文件流
        File newFile = new File(outPutFilePath);
        MultipartFile newMultipartFile;
        try {
            FileInputStream fileInputStream = new FileInputStream(newFile);
            newMultipartFile = new MockMultipartFile(file.getName(), fileInputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ImageException(e.getMessage());
        }
        //返回的数据
        Map<String, Object> resultMap = Maps.newHashMap();
        //压缩的文件
        resultMap.put("file", newMultipartFile);
        //压缩后文件的路径
        resultMap.put("location", outPutFilePath);
        return resultMap;
    }

    //加上水印
    public static void generateThumbnailUpload(File file) {
        try {
            Thumbnails
                    .of(file) //将要添加水印的图片
                    .size(337, 640) //加上水印后的尺寸大小
                    // .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "/image/watermark.jpg")),1.0F) //水印的生成位置，水印图片
                    .outputQuality(0.8f) //生成的质量
                    .toFile(file.getAbsolutePath());//生成图片的路径

        } catch (IOException e) {
            log.error("生成水印图片异常：{}", e.getMessage());
        }
    }

    private static void makeDirPath(String absolutePath) {
        try {
            File dirPath = new File(absolutePath);
            if (!dirPath.exists()) {//如果不存在
                dirPath.setWritable(true);//赋予可写权限
                dirPath.mkdirs();
            }
        } catch (Exception e) {
            log.error("生成目标文路径:" + absolutePath + "异常:{}", e.getMessage());
        }

    }

}